import { getBusinessObject, is, isAny } from "bpmn-js/lib/util/ModelUtil";
import { without } from "min-dash";
import editor from '@/store/editor'
import modeler from '@/store/modeler'
import {
  createModdleElement,
  getExtensionElementsList
} from '@/utils/BpmnExtensionElementsUtil'

/////// 功能函数
export function getFormValue(element) {
  const businessObject = getRelevantBusinessObject(element);

  if (!businessObject) return {};

  return getElementValue(businessObject) || {};
}

//设置实现方式
export function updateAttrs(element, attr) {
  const modeling = modeler().getModeling
  const businessObject = getRelevantBusinessObject(element);
  const prefix = editor().getProcessEngine
  const obj = {};
  // 拼接prefix
  Object.keys(attr).forEach(key => {
    obj[`${prefix}:${key}`] = attr[key];
  });
  removeConnector(element);
  modeling?.updateModdleProperties(element, businessObject, {
    ...obj
  });
}

//更新属性collection、elementVariable、acBefore、acAfter
export function updateConnector(element, value) {
  const modeling =modeler().getModeling
  const businessObject = getRelevantBusinessObject(element);
  const prefix = editor().getProcessEngine
  // 判断 extensionElements
  let extensionElements = businessObject.get("extensionElements");
  if (!extensionElements) {
    extensionElements = createModdleElement(
      "bpmn:ExtensionElements",
      { values: [] },
      businessObject
    );
    modeling?.updateModdleProperties(element, businessObject, {
      extensionElements
    });
  }
  let connector = getConnector(businessObject);
  if (!connector) {
    connector = createModdleElement(
      `${prefix}:Connector`,
      {},
      extensionElements
    );
    modeling?.updateModdleProperties(element, extensionElements, {
      values: [...extensionElements.get("values"), connector]
    });
  }
  modeling?.updateModdleProperties(element, connector, {
    "camunda:connectorId": value
  });
}

// 移除属性collection
export function removeConnector(element) {
  const businessObject = getRelevantBusinessObject(element);
  const extensionElements = businessObject.get("extensionElements");
  const connector = getConnector(businessObject);
  if (!connector) return;
  const modeling = modeler().getModeling
  modeling?.updateModdleProperties(element, extensionElements, {
    values: without(extensionElements.get("values"), connector)
  });
}

///// helpers
function getRelevantBusinessObject(element) {
  const businessObject = getBusinessObject(element);
  if (is(element, "bpmn:Participant")) {
    return businessObject.get("processRef");
  }
  return businessObject;
}

export function getElementValue(businessObject) {
  const prefix = editor().getProcessEngine
  const class_ = businessObject.get(`${prefix}:class`);
  const expression = businessObject.get(`${prefix}:expression`);
  const resultVariable = businessObject.get(`${prefix}:resultVariable`);
  const delegateExpression = businessObject.get(`${prefix}:delegateExpression`);
  const external = businessObject.get(`${prefix}:external`);
  const connector = getConnector(businessObject);
  const connectorId = getConnectorId(businessObject);
  let type = "none";
  if (class_ !== undefined) {
    type = "class";
  } else if (expression !== undefined || resultVariable !== undefined) {
    type = "expression";
  } else if (delegateExpression !== undefined) {
    type = "delegateExpression";
  } else if (external !== undefined) {
    type = "external";
  } else if (connector !== undefined) {
    type = "connector";
  }
  return {
    type: type,
    class: class_,
    expression: expression,
    resultVariable: resultVariable,
    delegateExpression: delegateExpression,
    external: external,
    connectorId: connectorId
  };
}

function getConnector(bo) {
  const extensionElementsList = getExtensionElementsList(bo);
  const prefix = editor().getProcessEngine
  return extensionElementsList.filter(
    ex => ex.$type === `${prefix}:Connector`
  )?.[0];
}

function getConnectorId(bo) {
  const extensionElementsList = getExtensionElementsList(bo);
  const prefix = editor().getProcessEngine
  const connector = extensionElementsList.filter(
    ex => ex.$type === `${prefix}:Connector`
  )?.[0];
  return connector?.connectorId;
}

export function isServiceTaskLike(element) {
  const task = [
    "bpmn:ServiceTask",
    "bpmn:BusinessRuleTask",
    "bpmn:SendTask",
    "bpmn:MessageEventDefinition"
  ];
  return isAny(element, task);
}
